//@ts-check
/**
 * 通用方法集合
 */
//MD5加密算法库
import MD5 from '../../libs/md5/MD5';
import store from '../store/index.js';


/**
 * 时间戳 -> 2020/01/03 16:25:22
 * @param { Number | String } time 时间(毫秒)
 * @param { String } format 格式
 * @returns { String } 2020/01/03 16:25:22s
 */
export function formatTime(time, format) {
	return dateToStrTime(new Date(time), format) //毫秒
}

/**
 * 数值 转为 字符串
 * 5 -> 05
 * 10 -> 10
 * @param { Number } n 要转换的数据
 */
function formatNumber(n) {
	let strN = n.toString()
	return strN[1] ? strN : '0' + strN
}

/**
 * 检测数据类型并返回类型
 * @param { * } data 数据
 * @returns { String } 数据类型
 */
export function checkDataType(data) {
	return Object.prototype.toString.call(data).slice(8, -1)
}

function staticSort(data) {
	return `{"sizeId":${data.sizeId},"productId":${data.productId},"count":${data.count}}`
}

/**
 * 获取md5加密串
 * @param { Object | Number | String } obj 要加密的数据
 * @param { Boolean? } bAddPrivateKey 是否添加私钥
 */
export const getMD5Sign = (obj, bAddPrivateKey = false) => {
	let dataType = checkDataType(obj)
	if (dataType === 'Object' || dataType === 'Number' || dataType === 'String') {
		let str = ''
		if (dataType === 'Object') {
			str = getSignUrl(sortObjByAscII(obj))
		}
		console.log(`${bAddPrivateKey ? str + '&key=' + store.state.privateKey : str}`);
		return MD5(`${bAddPrivateKey ? str + '&key=' + store.state.privateKey : str}`).toLowerCase()
	}
	return obj
}
export function getSignUrl(obj) {
	let str = ''
	Object.keys(obj).forEach(key => {
		if (obj[key]) {
			if (checkDataType(obj[key]) === 'Array') {
				str += `${key}=[`;
				obj[key].forEach((v, index) => {
					if (checkDataType(v) === 'Object') {
						str += staticSort(v) + ',';
					} else {
						str += JSON.stringify(v) + ','
					}
				});
				str = str.slice(0, -1);
				str += `]&`
			} else {
				str += `${key}=${obj[key]}&`
			}
		}
	});
	return str.slice(0, -1)
}

/**
 * ASCII排序(字典排序),返回对象
 * @param { Object } obj 对象
 * @param { Boolean? } bUp 是否为升序
 * @returns { Object } key值排好序的对象
 * 注意:
 *  虽然,将整个数组打印时,按照升序排序，但是利用for(let key in obj)时就能看出区别
 */
function sortObjByAscII(obj, bUp = true) {
	let arrKey = sortObjKeyByAscII(obj, bUp)
	let sortObj = {}
	arrKey.forEach(item => {
		sortObj[item] = obj[item]
	})
	return sortObj
}

function sortObjKeyByAscII(obj, bUp = true) {
	return sortArray(
		Object.keys(obj),
		bUp ? 1 : -1
	)
}

function sortArray(array = [], type = 1) {
	if (!Array.isArray(array)) return array
	return type !== 0 ?
		bubbleSort_oneWay(array, type) :
		array.sort(() => Math.random() - 0.5)
}

export function bubbleSort_oneWay(arr, iSortType = 1) {
	for (let i = 0; i < arr.length - 1; i++) {
		// 如果一轮比较中没有需要交换的数据，则说明数组已经有序。主要是对[5,1,2,3,4]之类的数组进行优化
		let mark = true
		for (let j = i + 1; j < arr.length; j++) {
			let bSortUpper = iSortType === 1
			let bExchange =
				(bSortUpper && arr[i] > arr[j]) || (!bSortUpper && arr[i] < arr[j])
			if (bExchange) {
				[arr[i], arr[j]] = [arr[j], arr[i]]
				mark = false
			}
		}
		if (mark) return arr
	}
	return arr
}


/**
 * 获取一个指定长度的随机字符串
 * @param { Number? } len 指定长度
 * @returns { String }
 */
export function getRandomText(len = 10) {
	if (len < 1) return ''
	let totalStr = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
	return totalStr[Math.floor(totalStr.length * Math.random())] + getRandomText(len - 1)
}
/**
 * 匹配手机号码
 * @param { String } str
 * @returns { null | String } 合法手机号，返回11位合法手机号;否则返回null
 */
export function phoneMatch(str) {
	if (!str || str === '') return ''
	let phone = str.replace('+86', '')
	phone = phone.replace(/[\ |\*|\,|\-]/g, '')
	let reg = new RegExp(
		'^((13[0-9])|(14[0,1,4,5,6,7,8,9])|(15([0-3]|[5-9]))|(16[2,5,6,7])|(17[0,1,2,3,4,5,6,7,8])|(18[0-9])|(19[1|8|9]))\\d{8}$',
		'g')
	return reg.test(phone) ? phone : null
}

/**
 * 转换手机号格式
 * 无效手机号时 返回11位*
 * 13260070228 => 132 6007 0228
 * 13260070228 => 132-6007-0228
 * @param { String | Number } strPhone 手机号字符串
 * @param { String= } char 连接字符
 * @return { String }
 */
export function convertPhone(strPhone, char = ' ') {
	let str = phoneMatch(strPhone.toString())
	str = str || '***********'
	return str.substr(0, 3) + char + str.substr(3, 4) + char + str.substr(7)
}

/**
 * 根据字符串中的数字 拆分字符串
 * 例如 abc123hkjhk => ["abc","123","hkjhk"]
 * @param { String } str
 * @returns { String[] }
 */
export function splitStrByNumber(str = '') {
	if (str.length === 0) return [];
	let arrNumber = str.match(/[0-9]+/g); //抽离出来的字符串-数字
	let arrStr = str.split(/[0-9]+/g); //抽出来的字符串-字符
	arrStr = arrStr.filter(v => v !== ''); //排除分离出来的空元素
	let bNumber = /[0-9]+/.test(str[0]); //判断是数值在前，还是字母在前
	return !arrNumber || arrNumber.length === 0 || arrStr.length === 0 ? [str.toString()] : joinNumberString(bNumber,
		arrNumber, arrStr);
}
/**
 * 拼接已经拆分出来的数值数组、字符串数组
 * @param { Boolean }  bNumberOfFirst 原字符串第一个字符是否数字
 * @param { String[] }  arrNumber 数值数组[字符串类型]
 * @param { String[] }  arrStr 字符串数组[字符串类型]
 */
export function joinNumberString(bNumberOfFirst, arrNumber, arrStr) {
	let arr = [];
	let moreLen = arrNumber.length - arrStr.length;
	let maxLength = moreLen > 0 ? arrNumber.length : arrStr.length;
	for (let i = 0; i < maxLength; ++i) {
		let arrTemp1 = bNumberOfFirst ? arrNumber : arrStr;
		let arrTemp2 = bNumberOfFirst ? arrStr : arrNumber;
		if (i < arrTemp1.length) arr.push(arrTemp1[i]);
		if (i < arrTemp2.length) arr.push(arrTemp2[i]);
	}
	return arr;
}

function fixNum(num, keepVal) {
	return parseFloat(parseFloat(num).toFixed(keepVal ? keepVal : 1));
}

function isNum(num) {
	return parseFloat(num) && Number(num);
}

function reFix(obj, keepVal) {
	Object.keys(obj).forEach(k => {
		const val = obj[k];
		if (isNum(val)) {
			obj[k] = fixNum(val, keepVal);
		}
		if (typeof val === "object") {
			reFix(val, keepVal);
		}
	});
}

/**
 * 将类似3.399999的数转成3.4
 * keepVal为保留位数（默认保留1位）
 * @param obj 支持任意类型参数
 * @param {number=}keepVal 支持任意类型参数
 */
export function translateNum(obj, keepVal = 2) {
	if (!obj) return obj;
	if (typeof obj === "object") {
		const cloneObj = JSON.parse(JSON.stringify(obj));
		reFix(cloneObj, keepVal);
		return cloneObj;
	}
	if (isNum(obj)) {
		return fixNum(obj, keepVal);
	}
	return obj;
}

/**
 * 倒计时文案样式
 * >=24小时 *天*小时
 * <24小时 时:分:秒
 * @param {number} leftTime 剩余时间
 * @returns {string}
 */
export function getCutdownTime(leftTime) {
	let secondsPerHour = 60 * 60;
	let secondsPerDay = secondsPerHour * 24;
	if (leftTime >= secondsPerDay) {
		let day = Math.floor(leftTime / secondsPerDay);
		return `${day}天${Math.floor((leftTime - day * secondsPerDay) / secondsPerHour)}小时`;
	} else {
		return formatSeconds(leftTime);
	}
}

/** 
 * 将数字转化为时分秒 
 * @param {*} value
 * */
export function formatSeconds(value) {
	if (value < 0) {
		console.warn("传值异常(%s)", value);
		return "00:00:00";
	}
	let secondTime = parseInt(value); // 秒
	let minuteTime = 0; // 分
	let hourTime = 0; // 小时
	if (secondTime > 60) { //如果秒数大于60，将秒数转换成整数
		//获取分钟，除以60取整数，得到整数分钟
		minuteTime = parseInt(secondTime / 60 + '');
		//获取秒数，秒数取佘，得到整数秒数
		secondTime = parseInt(secondTime % 60 + '');
		//如果分钟大于60，将分钟转换成小时
		if (minuteTime > 60) {
			//获取小时，获取分钟除以60，得到整数小时
			hourTime = parseInt(minuteTime / 60 + '');
			//获取小时后取佘的分，获取分钟除以60取佘的分
			minuteTime = parseInt(minuteTime % 60 + '');
		}
	}
	let s = parseInt(secondTime + '');
	let result = "" + (s >= 10 ? s : "0" + s);
	if (minuteTime > 0) {
		let m = parseInt(minuteTime + '');
		result = "" + (m >= 10 ? m : "0" + m) + ":" + result;
	} else {
		result = "00:" + result;
	}
	if (hourTime > 0) {
		let h = parseInt(hourTime + '');
		result = "" + (h >= 10 ? h : "0" + h) + ":" + result;
	} else {
		result = "00:" + result;
	}
	return result;
}
